package _11_整理题目._6_模拟设计._位运算;

import org.junit.Test;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * https://leetcode-cn.com/problems/single-number/
 * 给定一个非空整数数组，除了某个元素只出现一次以外，其余每个元素均出现两次。
 * 找出那个只出现了一次的元素
 * 要求，o(n)时间，o(1)空间
 *
 * 位运算特性：
 *      a ^ a = 0
 *      0 ^ a = a
 *      满足交换律和结合律
 *
 * 使用 hashmap，o(n)时间，o(n)空间
 * 先排序再遍历，o(nlogn)时间，o(1)空间
 */
public class _01_只出现一次的一个数 {

    // 位运算
    public int singleNumber(int[] nums) {
        int result = 0;
        for (int num : nums) {
            result ^= num;
        }
        return result;
    }

    @Test
    public void main() {
        int[] nums = {4,1,2,1,2};
        System.out.println(singleNumber(nums));
        System.out.println(singleNumber2(nums));
    }

    // HashSet，消消乐，如果存在就移除，不存在就加入
    public int singleNumber2(int[] nums) {
        Set<Integer> set = new HashSet<>();
        for (int num : nums) {
            if (set.contains(num)) {
                set.remove(num);
            } else {
                set.add(num);
            }
        }
        return set.iterator().next();
    }
    // HashMap
    public int singleNumber3(int[] nums) {
        Map<Integer, Integer> map = new HashMap<>();
        for (int num : nums) {
            map.put(num, map.getOrDefault(num,0)+1);
        }
        for (int key : nums) {
            if (map.get(key) == 1) return key;
        }
        return 0;
    }
}
